#!/usr/bin/python
#coding=utf-8
from app.dbutils import DBUtils
from igor import logging
import MySQLdb
from MySQLdb.cursors import DictCursor

class OrderState(object):
    FAIL, LESS_MONEY, NOTEXIST, PAYED, SUCC = range(5)


class Order(object):

    def __init__(self, bid=None, orderid=None, amount=None, 
        moneytype=None, mallid=None, expire=None, bdate=None, 
        returnurl=None, status=None):
        self.bid = bid
        self.orderid = orderid
        self.amount = amount
        self.moneytype = moneytype
        self.mallid = mallid
        self.expire = expire
        self.bdate = bdate
        self.returnurl = returnurl
        self.status = status


class OrderManager(object):

    def __init__(self):
        self.dbutils = DBUtils()

    def insert(self, bid, orderid, amount, moneytype, mallid,
            expire, returnurl, status):
        sql = """
            INSERT INTO bankorder(bid, orderid, amount,
                 moneytype, mallid, expire, returnurl, status) 
            VALUES(%s, %s, %s, %s, %s, %s, %s, %s)
        """
        params = (bid, orderid, amount, moneytype, mallid, 
            expire, returnurl, status)
        rows = self.dbutils.execute(sql, params)
        if rows is None:
            return False 
        return True 

    def update(self, bid, cardid, mall_cardid):
        sql_order = """
            SELECT status, amount FROM bankorder WHERE bid=%s
            FOR UPDATE
        """
        sql_order_update = """
            UPDATE bankorder SET status=1, cardid=%s WHERE bid=%s
        """
        sql_user = """
            SELECT cardid, money FROM user WHERE cardid=%s OR cardid=%s FOR UPDATE
        """
        sql_user_update = """
            UPDATE user SET money=%s WHERE cardid=%s
        """
        try:
            conn = self.dbutils.connect()
            cursor = conn.cursor(DictCursor)
            cursor.execute(sql_order, (bid, ))
            row = cursor.fetchone()
            if not row:
                conn.rollback()
                return OrderState.NOTEXIST
            status = row['status']
            amount = row['amount']
            if status == 1:
                conn.rollback()
                return OrderState.PAYED 
            cursor.execute(sql_user, (cardid, mall_cardid))
            rows = cursor.fetchall()
            if not rows:
                conn.rollback()
                return OrderState.FAIL
            records = {}
            for row in rows:
                cardid = row['cardid']
                records[cardid] = row['money']
            user_money = records[cardid]
            mall_money = records[mall_cardid]
            if user_money < amount:
                conn.rollback()
                return OrderState.LESS_MONEY 
            users = []  
            users.append((user_money - amount, cardid))
            users.append((mall_money + amount, mall_cardid))
            cursor.executemany(sql_user_update, users)
            cursor.execute(sql_order_update, (cardid, bid))
            conn.commit()
        except MySQLdb.Error, err:
            logging.log(err)
            conn.rollback()
            return OrderState.FAIL 
        except Exception, err:
            logging.log(err)
            conn.rollback()
            return OrderState.FAIL 
        return OrderState.SUCC 

    def query(self, orderid, mallid):
        sql = """
            SELECT * FROM bankorder WHERE orderid=%s AND mallid=%s
        """
        rows = self.dbutils.execute_dict(sql, (orderid, mallid))
        if rows:
            row = rows[0]
            amount = row['amount']
            moneytype = row['moneytype']
            expire = row['expire']
            bdate = row['bdate']
            status = row['status']
            order = Order(orderid=orderid, amount=amount, moneytype=moneytype, 
                mallid=mallid, expire=expire, bdate=bdate, status=status)
            return order
        return None

    def query_by_bid(self, bid):
        sql = """
            SELECT * FROM bankorder WHERE bid=%s 
        """
        rows = self.dbutils.execute_dict(sql, (bid,))
        if rows:
            row = rows[0]
            orderid = row['orderid']
            amount = row['amount']
            moneytype = row['moneytype']
            mallid = row['mallid']
            expire = row['expire']
            bdate = row['bdate']
            returnurl = row['returnurl']
            status = row['status']
            order = Order(bid=bid, orderid=orderid, amount=amount, moneytype=moneytype, 
                mallid=mallid, expire=expire, bdate=bdate, returnurl=returnurl, status=status)
            return order
        return None
